#include "hook.h"

#include <string>

using namespace std::literals::string_view_literals;

BOOL WINAPI get_message(LPMSG msg, HWND hwnd, UINT msg_filter_min, UINT msg_filter_max)
{
    if (msg->message == WM_KEYDOWN)
        ::MessageBoxA(NULL, "keydown", "", MB_OK);

    const auto original = windows::hook::get_function_address("User32.dll", "GetMessageW"sv).original;

    return reinterpret_cast<BOOL (*)(LPMSG, HWND, UINT, UINT)>(original)(msg, hwnd, msg_filter_min, msg_filter_max);
}

BOOL WINAPI read_console(HANDLE console_input, LPVOID buffer, DWORD number_chars_to_read, LPDWORD number_chars_read, LPVOID control)
{
    const auto original = windows::hook::get_function_address("Kerne32.dll", "ReadConsole").original;
    const auto result = reinterpret_cast<BOOL (*)(HANDLE, LPVOID, DWORD, LPDWORD, LPVOID)>(original)(console_input, buffer, number_chars_to_read, number_chars_read, control);

    ::MessageBoxA(NULL, reinterpret_cast<const char*>(buffer), "", MB_OK);

    return result;
}

BOOL WINAPI DllMain(HINSTANCE hinstance, DWORD reason, PVOID load)
{
    switch (reason)
    {
    case DLL_PROCESS_ATTACH:
    {
        windows::hook::get_or_create({{"User32.dll"sv, {{"GetMessageW"sv, reinterpret_cast<PROC>(get_message)}}},
            {"Kernel32.dll"sv, {{"ReadConsole"sv, reinterpret_cast<PROC>(read_console)}}}});
        break;
    }
    case DLL_PROCESS_DETACH:
    {
        windows::hook::get_or_create().release();
        break;
    }
    }

    return TRUE;
}
